1   /*
2    * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions
6    * are met:
7    *
8    *   - Redistributions of source code must retain the above copyright
9    *     notice, this list of conditions and the following disclaimer.
10   *
11   *   - Redistributions in binary form must reproduce the above copyright
12   *     notice, this list of conditions and the following disclaimer in the
13   *     documentation and/or other materials provided with the distribution.
14   *
15   *   - Neither the name of Oracle nor the names of its
16   *     contributors may be used to endorse or promote products derived
17   *     from this software without specific prior written permission.
18   *
19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20   * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  
32  
33  import javax.swing.*;
34  import javax.swing.table.*;
35  import javax.swing.border.*;
36  import java.awt.Dimension;
37  import java.awt.event.WindowAdapter;
38  import java.awt.event.WindowEvent;
39  import java.awt.Color;
40  import java.util.logging.Level;
41  import java.util.logging.Logger;
42  import javax.swing.UIManager.LookAndFeelInfo;
43  
44  
45  /**
46   * Another JTable example, showing how column attributes can be refined
47   * even when columns have been created automatically. Here we create some
48   * specialised renderers and editors as well as changing widths and colors
49   * for some of the columns in the SwingSet demo table.
50   *
51   * @author Philip Milne
52   */
53  public class TableExample4 {
54  
55      public TableExample4() {
56          JFrame frame = new JFrame("Table");
57          frame.addWindowListener(new WindowAdapter() {
58  
59              @Override
60              public void windowClosing(WindowEvent e) {
61                  System.exit(0);
62              }
63          });
64  
65          // Take the dummy data from SwingSet.
66          final String[] names = { "First Name", "Last Name", "Favorite Color",
67              "Favorite Number", "Vegetarian" };
68          final Object[][] data = {
69              { "Mark", "Andrews", "Red", new Integer(2), Boolean.TRUE },
70              { "Tom", "Ball", "Blue", new Integer(99), Boolean.FALSE },
71              { "Alan", "Chung", "Green", new Integer(838), Boolean.FALSE },
72              { "Jeff", "Dinkins", "Turquois", new Integer(8), Boolean.TRUE },
73              { "Amy", "Fowler", "Yellow", new Integer(3), Boolean.FALSE },
74              { "Brian", "Gerhold", "Green", new Integer(0), Boolean.FALSE },
75              { "James", "Gosling", "Pink", new Integer(21), Boolean.FALSE },
76              { "David", "Karlton", "Red", new Integer(1), Boolean.FALSE },
77              { "Dave", "Kloba", "Yellow", new Integer(14), Boolean.FALSE },
78              { "Peter", "Korn", "Purple", new Integer(12), Boolean.FALSE },
79              { "Phil", "Milne", "Purple", new Integer(3), Boolean.FALSE },
80              { "Dave", "Moore", "Green", new Integer(88), Boolean.FALSE },
81              { "Hans", "Muller", "Maroon", new Integer(5), Boolean.FALSE },
82              { "Rick", "Levenson", "Blue", new Integer(2), Boolean.FALSE },
83              { "Tim", "Prinzing", "Blue", new Integer(22), Boolean.FALSE },
84              { "Chester", "Rose", "Black", new Integer(0), Boolean.FALSE },
85              { "Ray", "Ryan", "Gray", new Integer(77), Boolean.FALSE },
86              { "Georges", "Saab", "Red", new Integer(4), Boolean.FALSE },
87              { "Willie", "Walker", "Phthalo Blue", new Integer(4), Boolean.FALSE },
88              { "Kathy", "Walrath", "Blue", new Integer(8), Boolean.FALSE },
89              { "Arnaud", "Weber", "Green", new Integer(44), Boolean.FALSE }
90          };
91  
92          // Create a model of the data.
93          @SuppressWarnings("serial")
94          TableModel dataModel = new AbstractTableModel() {
95              // These methods always need to be implemented.
96  
97              public int getColumnCount() {
98                  return names.length;
99              }
100 
101             public int getRowCount() {
102                 return data.length;
103             }
104 
105             public Object getValueAt(int row, int col) {
106                 return data[row][col];
107             }
108 
109             // The default implementations of these methods in
110             // AbstractTableModel would work, but we can refine them.
111             @Override
112             public String getColumnName(int column) {
113                 return names[column];
114             }
115 
116             @Override
117             public Class getColumnClass(int c) {
118                 return getValueAt(0, c).getClass();
119             }
120 
121             @Override
122             public boolean isCellEditable(int row, int col) {
123                 return true;
124             }
125 
126             @Override
127             public void setValueAt(Object aValue, int row, int column) {
128                 System.out.println("Setting value to: " + aValue);
129                 data[row][column] = aValue;
130             }
131         };
132 
133         // Create the table
134         JTable tableView = new JTable(dataModel);
135         // Turn off auto-resizing so that we can set column sizes
136         // programmatically. In this mode, all columns will get their preferred
137         // widths, as set blow.
138         tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
139 
140         // Create a combo box to show that you can use one in a table.
141         JComboBox comboBox = new JComboBox();
142         comboBox.addItem("Red");
143         comboBox.addItem("Orange");
144         comboBox.addItem("Yellow");
145         comboBox.addItem("Green");
146         comboBox.addItem("Blue");
147         comboBox.addItem("Indigo");
148         comboBox.addItem("Violet");
149 
150         TableColumn colorColumn = tableView.getColumn("Favorite Color");
151         // Use the combo box as the editor in the "Favorite Color" column.
152         colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
153 
154         // Set a pink background and tooltip for the Color column renderer.
155         DefaultTableCellRenderer colorColumnRenderer =
156                 new DefaultTableCellRenderer();
157         colorColumnRenderer.setBackground(Color.pink);
158         colorColumnRenderer.setToolTipText("Click for combo box");
159         colorColumn.setCellRenderer(colorColumnRenderer);
160 
161         // Set a tooltip for the header of the colors column.
162         TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
163         if (headerRenderer instanceof DefaultTableCellRenderer) {
164             ((DefaultTableCellRenderer) headerRenderer).setToolTipText(
165                     "Hi Mom!");
166         }
167 
168         // Set the width of the "Vegetarian" column.
169         TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
170         vegetarianColumn.setPreferredWidth(100);
171 
172         // Show the values in the "Favorite Number" column in different colors.
173         TableColumn numbersColumn = tableView.getColumn("Favorite Number");
174         @SuppressWarnings("serial")
175         DefaultTableCellRenderer numberColumnRenderer
176                 = new DefaultTableCellRenderer() {
177 
178             @Override
179             public void setValue(Object value) {
180                 int cellValue = (value instanceof Number) ? ((Number) value).
181                         intValue() : 0;
182                 setForeground((cellValue > 30) ? Color.black : Color.red);
183                 setText((value == null) ? "" : value.toString());
184             }
185         };
186         numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
187         numbersColumn.setCellRenderer(numberColumnRenderer);
188         numbersColumn.setPreferredWidth(110);
189 
190         // Finish setting up the table.
191         JScrollPane scrollpane = new JScrollPane(tableView);
192         scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));
193         scrollpane.setPreferredSize(new Dimension(430, 200));
194         frame.getContentPane().add(scrollpane);
195         frame.pack();
196         frame.setVisible(true);
197     }
198 
199     public static void main(String[] args) {
200         // Trying to set Nimbus look and feel
201         try {
202             for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
203                 if ("Nimbus".equals(info.getName())) {
204                     UIManager.setLookAndFeel(info.getClassName());
205                     break;
206                 }
207             }
208         } catch (Exception ex) {
209             Logger.getLogger(TableExample4.class.getName()).log(Level.SEVERE,
210                     "Failed to apply Nimbus look and feel", ex);
211         }
212 
213         new TableExample4();
214     }
215 }